"""
MicroBlog - 轻量级Flask博客系统
"""

import os
import json
import datetime
from flask import Flask, render_template, request, redirect, url_for, session, flash, jsonify
from werkzeug.security import check_password_hash, generate_password_hash
from markdown import parse_markdown
import secrets

app = Flask(__name__)
app.secret_key = secrets.token_hex(16)

# 配置
DATABASE_FILE = 'database.json'
CONTENT_DIR = 'content'
POSTS_DIR = os.path.join(CONTENT_DIR, 'posts')
PAGES_DIR = os.path.join(CONTENT_DIR, 'pages')
RENDERED_DIR = os.path.join(CONTENT_DIR, 'rendered')
RENDERED_POSTS_DIR = os.path.join(RENDERED_DIR, 'posts')
RENDERED_PAGES_DIR = os.path.join(RENDERED_DIR, 'pages')

# 确保目录存在
for directory in [CONTENT_DIR, POSTS_DIR, PAGES_DIR, RENDERED_DIR, RENDERED_POSTS_DIR, RENDERED_PAGES_DIR]:
    os.makedirs(directory, exist_ok=True)


def load_env():
    """加载.env文件中的配置"""
    env_vars = {}
    if os.path.exists('.env'):
        with open('.env', 'r', encoding='utf-8') as f:
            for line in f:
                line = line.strip()
                if line and '=' in line:
                    key, value = line.split('=', 1)
                    env_vars[key] = value
    return env_vars


def init_database():
    """初始化数据库文件"""
    if not os.path.exists(DATABASE_FILE):
        default_data = {
            "settings": {
                "site_title": "我的博客",
                "site_logo": "🌟",
                "description": "一个简洁的个人博客"
            },
            "posts": [],
            "pages": []
        }
        save_database(default_data)
        return default_data
    return load_database()


def load_database():
    """加载数据库"""
    try:
        with open(DATABASE_FILE, 'r', encoding='utf-8') as f:
            return json.load(f)
    except (FileNotFoundError, json.JSONDecodeError):
        return init_database()


def save_database(data):
    """保存数据库"""
    with open(DATABASE_FILE, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=2)


def get_next_id(items):
    """获取下一个可用ID"""
    if not items:
        return 1
    return max(item['id'] for item in items) + 1


def save_content_files(content_id, content_type, title, markdown_content):
    """保存内容文件（markdown和渲染后的HTML）"""
    # 确定文件路径
    if content_type == 'post':
        md_file = os.path.join(POSTS_DIR, f'{content_id}.md')
        html_file = os.path.join(RENDERED_POSTS_DIR, f'{content_id}.html')
    else:  # page
        md_file = os.path.join(PAGES_DIR, f'{content_id}.md')
        html_file = os.path.join(RENDERED_PAGES_DIR, f'{content_id}.html')
    
    # 保存markdown文件
    with open(md_file, 'w', encoding='utf-8') as f:
        f.write(markdown_content)
    
    # 渲染并保存HTML文件
    html_content = parse_markdown(markdown_content)
    with open(html_file, 'w', encoding='utf-8') as f:
        f.write(html_content)
    
    return md_file, html_file


def load_content_file(file_path):
    """加载内容文件"""
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            return f.read()
    except FileNotFoundError:
        return ""


def require_admin(f):
    """管理员权限装饰器"""
    def decorated_function(*args, **kwargs):
        if not session.get('admin_logged_in'):
            return redirect(url_for('admin_login'))
        return f(*args, **kwargs)
    decorated_function.__name__ = f.__name__
    return decorated_function


# 前台路由
@app.route('/')
def index():
    """首页 - 显示文章列表"""
    data = load_database()
    posts = [post for post in data['posts'] if post.get('published', True)]
    posts.sort(key=lambda x: x['created_at'], reverse=True)
    pages = [page for page in data['pages'] if page.get('published', True)]
    
    return render_template('index.html', 
                         posts=posts, 
                         pages=pages,
                         settings=data['settings'])


@app.route('/post/<slug>')
def post_detail(slug):
    """文章详情页"""
    data = load_database()
    post = None
    pages = [page for page in data['pages'] if page.get('published', True)]
    
    for p in data['posts']:
        if p['slug'] == slug and p.get('published', True):
            post = p
            break
    
    if not post:
        return render_template('404.html'), 404
    
    # 加载渲染后的HTML内容
    html_content = load_content_file(post['html_file'])
    
    return render_template('post.html', 
                         post=post, 
                         content=html_content,
                         pages=pages,
                         settings=data['settings'])


@app.route('/page/<slug>')
def page_detail(slug):
    """页面详情"""
    data = load_database()
    page = None
    pages = [page for page in data['pages'] if page.get('published', True)]
    
    for p in data['pages']:
        if p['slug'] == slug and p.get('published', True):
            page = p
            break
    
    if not page:
        return render_template('404.html'), 404
    
    # 加载渲染后的HTML内容
    html_content = load_content_file(page['html_file'])
    
    return render_template('page.html', 
                         page=page, 
                         content=html_content,
                         pages=pages,
                         settings=data['settings'])


# 管理后台路由
@app.route('/admin')
def admin_login():
    """管理员登录页"""
    if session.get('admin_logged_in'):
        return redirect(url_for('admin_dashboard'))
    return render_template('admin/login.html')


@app.route('/admin/login', methods=['POST'])
def admin_login_post():
    """处理管理员登录"""
    env_vars = load_env()
    username = request.form.get('username')
    password = request.form.get('password')
    
    if username == env_vars.get('name') and password == env_vars.get('passwd'):
        session['admin_logged_in'] = True
        flash('登录成功！', 'success')
        return redirect(url_for('admin_dashboard'))
    else:
        flash('用户名或密码错误！', 'error')
        return redirect(url_for('admin_login'))


@app.route('/admin/logout')
def admin_logout():
    """管理员退出登录"""
    session.pop('admin_logged_in', None)
    flash('已退出登录！', 'info')
    return redirect(url_for('index'))


@app.route('/admin/dashboard')
@require_admin
def admin_dashboard():
    """管理后台首页"""
    data = load_database()
    return render_template('admin/dashboard.html', 
                         posts=data['posts'], 
                         pages=data['pages'],
                         settings=data['settings'])


@app.route('/admin/posts')
@require_admin
def admin_posts():
    """文章管理"""
    data = load_database()
    return render_template('admin/posts.html', 
                         posts=data['posts'],
                         settings=data['settings'])


@app.route('/admin/pages')
@require_admin
def admin_pages():
    """页面管理"""
    data = load_database()
    return render_template('admin/pages.html', 
                         pages=data['pages'],
                         settings=data['settings'])


@app.route('/admin/editor/post')
@app.route('/admin/editor/post/<int:post_id>')
@require_admin
def admin_post_editor(post_id=None):
    """文章编辑器"""
    data = load_database()
    post = None
    
    if post_id:
        for p in data['posts']:
            if p['id'] == post_id:
                post = p
                # 加载markdown内容
                post['markdown_content'] = load_content_file(post['md_file'])
                break
    
    return render_template('admin/editor.html', 
                         post=post, 
                         content_type='post',
                         settings=data['settings'])


@app.route('/admin/editor/page')
@app.route('/admin/editor/page/<int:page_id>')
@require_admin
def admin_page_editor(page_id=None):
    """页面编辑器"""
    data = load_database()
    page = None
    
    if page_id:
        for p in data['pages']:
            if p['id'] == page_id:
                page = p
                # 加载markdown内容
                page['markdown_content'] = load_content_file(page['md_file'])
                break
    
    return render_template('admin/editor.html', 
                         post=page, 
                         content_type='page',
                         settings=data['settings'])


@app.route('/admin/save_content', methods=['POST'])
@require_admin
def save_content():
    """保存内容（文章或页面）"""
    data = load_database()
    
    content_type = request.form.get('content_type')  # 'post' or 'page'
    content_id = request.form.get('id')
    title = request.form.get('title')
    slug = request.form.get('slug')
    markdown_content = request.form.get('content')
    published = request.form.get('published') == 'on'
    
    if not title or not slug or not markdown_content:
        return jsonify({'success': False, 'message': '请填写所有必填字段'})
    
    now = datetime.datetime.now().isoformat()
    
    if content_id:  # 编辑现有内容
        content_id = int(content_id)
        items = data['posts'] if content_type == 'post' else data['pages']
        
        for item in items:
            if item['id'] == content_id:
                item['title'] = title
                item['slug'] = slug
                item['published'] = published
                item['updated_at'] = now
                
                # 保存文件
                md_file, html_file = save_content_files(content_id, content_type, title, markdown_content)
                item['md_file'] = md_file
                item['html_file'] = html_file
                break
    else:  # 创建新内容
        items = data['posts'] if content_type == 'post' else data['pages']
        content_id = get_next_id(items)
        
        # 保存文件
        md_file, html_file = save_content_files(content_id, content_type, title, markdown_content)
        
        new_item = {
            'id': content_id,
            'title': title,
            'slug': slug,
            'md_file': md_file,
            'html_file': html_file,
            'created_at': now,
            'updated_at': now,
            'published': published,
            'type': content_type
        }
        
        items.append(new_item)
    
    save_database(data)
    return jsonify({'success': True, 'message': f'{"文章" if content_type == "post" else "页面"}保存成功'})


@app.route('/admin/delete_content', methods=['POST'])
@require_admin
def delete_content():
    """删除内容"""
    data = load_database()
    
    content_type = request.form.get('content_type')
    content_id = int(request.form.get('id'))
    
    items = data['posts'] if content_type == 'post' else data['pages']
    
    for i, item in enumerate(items):
        if item['id'] == content_id:
            # 删除文件
            try:
                os.remove(item['md_file'])
                os.remove(item['html_file'])
            except FileNotFoundError:
                pass
            
            # 从数据库中删除
            items.pop(i)
            break
    
    save_database(data)
    return jsonify({'success': True, 'message': f'{"文章" if content_type == "post" else "页面"}删除成功'})


@app.route('/admin/settings')
@require_admin
def admin_settings():
    """网站设置"""
    data = load_database()
    return render_template('admin/settings.html', settings=data['settings'])


@app.route('/admin/save_settings', methods=['POST'])
@require_admin
def save_settings():
    """保存网站设置"""
    data = load_database()
    
    data['settings']['site_title'] = request.form.get('site_title', '')
    data['settings']['site_logo'] = request.form.get('site_logo', '')
    data['settings']['description'] = request.form.get('description', '')
    
    save_database(data)
    flash('设置保存成功！', 'success')
    return redirect(url_for('admin_settings'))


@app.route('/api/preview', methods=['POST'])
@require_admin
def preview_markdown():
    """预览Markdown内容"""
    markdown_content = request.json.get('content', '')
    html_content = parse_markdown(markdown_content)
    return jsonify({'html': html_content})


if __name__ == '__main__':
    # 初始化数据库
    init_database()
    
    # 运行应用
    app.run(debug=True, host='0.0.0.0', port=5000)
